/* eslint-disable @typescript-eslint/no-explicit-any */
import { motion } from 'motion/react';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PaginationProps, SortProps, TreeNode } from '~/types';

// Define the props for TableTree
interface TableProps {
  data: TreeNode[];
  dataCount: number; // 0：不分页
  treeable?: boolean; // 是否开启树形结构
  onTableChange?: (paginationProps: PaginationProps, sortProps: SortProps | null) => void;
  pageSizes?: number[], // 分页大小选项
  pageSize?: number; // 默认分页大小
  isLoading?: boolean;
  columns: {
    id: string; // 唯一
    key?: string; // data的键，默认为id值
    name: string; // th name
    sortable?: boolean; // 节点可排序
    indentable?: boolean; // 节点可缩进
    className?: string;
    render?: (value: any) => React.ReactNode;
  }[];
}

// Define the state for expanded nodes
type ExpandedState = Record<string, boolean>;

export const Table: React.FC<TableProps> = (props: TableProps) => {
  const { t } = useTranslation();
  const [expanded, setExpanded] = useState<ExpandedState>({});

  // Sort
  const [sortColumn, setSortColumn] = React.useState<SortProps | null>(null);
  const handleSort = (column: string, sortable: boolean) => {
    if (!sortable) return;
    let newSortColumn: SortProps | null;
    if (sortColumn?.column === column) {
      if (sortColumn.order === 'asc') {
        newSortColumn = {
          ...sortColumn,
          order: 'desc',
        };
      } else {
        newSortColumn = null;
      }
    } else {
      newSortColumn = { column, order: 'asc' };
    }
    const newPagination = { page: 1, pageSize: pagination.pageSize };
    if (props.onTableChange) {
      props.onTableChange(newPagination, newSortColumn);
    }
    setPagination(newPagination);
    setSortColumn(newSortColumn);
  }

  // Paginate
  const [pagination, setPagination] = useState<PaginationProps>({ page: 1, pageSize: 10 });
  useEffect(() => {
    if (props.pageSize) {
      setPagination({ page: 1, pageSize: props.pageSize });
    } else {
      setPagination({ page: 1, pageSize: 10 });
    }
  }, [props.pageSize]);
  const handlePaginate = (page: number, pageSize: number) => {
    setPagination({ page, pageSize });
    if (props.onTableChange) {
      props.onTableChange({ page, pageSize }, sortColumn);
    }
  };
  const renderPagination = () => {
    if (!props.dataCount) return null;
    const dataCount = props.dataCount;
    const totalPages = Math.ceil(dataCount / pagination.pageSize);
    const start = pagination.page === 1 ? 1 : (pagination.page - 1) * pagination.pageSize;
    const end = Math.min(pagination.page * pagination.pageSize, dataCount);

    return (
      <div className="flex items-center mt-5">
        <div className="join">
          <button
            className={`join-item btn ${pagination.page === 1 ? "btn-disabled" : ""}`}
            onClick={() => handlePaginate(pagination.page - 1, pagination.pageSize)}
          >
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
              <path strokeLinecap="round" strokeLinejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
            </svg>
          </button>
          {
            Array.from({ length: totalPages }, (_, i) => (
              <button
                key={i}
                className={`join-item btn ${pagination.page === (i + 1) ? "btn-primary" : ""}`}
                onClick={() => pagination.page === (i + 1) ? null : handlePaginate(i + 1, pagination.pageSize)}
              >
                {i + 1}
              </button>
            ))
          }
          <button
            className={`join-item btn ${pagination.page === totalPages ? "btn-disabled" : ""}`}
            onClick={() => handlePaginate(pagination.page + 1, pagination.pageSize)}
          >
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
              <path strokeLinecap="round" strokeLinejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
            </svg>
          </button>
        </div>
        <div className="flex items-center ml-4">
          <span className="text-neutral-400">{t("table.rows_per_page")}</span>
          <select
            className="select select-bordered select-sm w-15 ml-2"
            value={pagination.pageSize}
            onChange={(e) => handlePaginate(1, Number(e.target.value))}>
            {
              props.pageSizes
                ? props.pageSizes?.map((size) => (
                  <option key={size} value={size}>{size}</option>
                ))
                : (
                  <>
                    <option value="10">10</option>
                    <option value="30">25</option>
                    <option value="50">50</option>
                  </>
                )
            }
          </select>
          <span className="ml-4"> {start}-{end} {t("table.of")} {dataCount}</span>
        </div>
      </div>
    )
  }

  // Toggle the expansion state of a node
  const toggleNode = (id: string) => {
    setExpanded((prevExpanded) => ({
      ...prevExpanded,
      [id]: !prevExpanded[id],
    }));
  };

  // Recursive function to render tree nodes
  const renderTreeNode = (node: TreeNode, level: number = 0): JSX.Element => {
    const hasChildren = node.children && node.children.length > 0;
    return (
      <React.Fragment key={node.id}>
        <motion.tr key={node.id} layout
          initial={{ y: -30, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          exit={{ y: -30, opacity: 0 }}
        >
          {props.columns.map((column, index) => (
            <td key={index} style={level && column.indentable ? { paddingLeft: `${level * 20 + 16}px` } : {}} className={index === 0 && hasChildren ? " flex items-center" : ""}>
              {index === 0 && hasChildren
                ? (
                  <button
                    onClick={() => toggleNode(node.id)}
                    className='btn btn-ghost btn-circle btn-xs mr-1'
                  >
                    {expanded[node.id]
                      ? <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor" className="size-5 text-yellow-500">
                        <path strokeLinecap="round" strokeLinejoin="round" d="M3.75 9.776c.112-.017.227-.026.344-.026h15.812c.117 0 .232.009.344.026m-16.5 0a2.25 2.25 0 0 0-1.883 2.542l.857 6a2.25 2.25 0 0 0 2.227 1.932H19.05a2.25 2.25 0 0 0 2.227-1.932l.857-6a2.25 2.25 0 0 0-1.883-2.542m-16.5 0V6A2.25 2.25 0 0 1 6 3.75h3.879a1.5 1.5 0 0 1 1.06.44l2.122 2.12a1.5 1.5 0 0 0 1.06.44H18A2.25 2.25 0 0 1 20.25 9v.776" />
                      </svg>
                      : <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor" className="size-5 text-yellow-500">
                        <path strokeLinecap="round" strokeLinejoin="round" d="M2.25 12.75V12A2.25 2.25 0 0 1 4.5 9.75h15A2.25 2.25 0 0 1 21.75 12v.75m-8.69-6.44-2.12-2.12a1.5 1.5 0 0 0-1.061-.44H4.5A2.25 2.25 0 0 0 2.25 6v12a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9a2.25 2.25 0 0 0-2.25-2.25h-5.379a1.5 1.5 0 0 1-1.06-.44Z" />
                      </svg>
                    }
                  </button>
                )
                : null
              }
              {column.render ? column.render(node) : node[column.key || column.id]}
            </td>
          ))}
        </motion.tr>
        {hasChildren
          && expanded[node.id]
          && node.children?.map((child: TreeNode) => renderTreeNode(child, level + 1))}
      </React.Fragment>
    );
  };

  return (
    <>
      <table className="table">
        <thead className="bg-base-200 text-lg">
          <tr>
            {props.columns.map((column, index) => {
              return (
                <th key={index} className={column.className || ''}>
                  <div className='flex items-center'>
                    <span
                      role="button"
                      tabIndex={0}
                      onClick={() => handleSort(column.key || column.id, column.sortable || false)}
                      className={(column.className ?? "") + (!column.sortable ? ' cursor-default' : '')}
                      onKeyDown={() => { }}
                    >
                      {column.name}
                    </span>
                    {sortColumn?.column === column.id && (
                      sortColumn?.order == 'asc'
                        ? <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={3} stroke="currentColor" className="size-4 ml-1">
                          <path strokeLinecap="round" strokeLinejoin="round" d="m4.5 15.75 7.5-7.5 7.5 7.5" />
                        </svg>
                        : <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={3} stroke="currentColor" className="size-4 ml-1">
                          <path strokeLinecap="round" strokeLinejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
                        </svg>
                    )}
                  </div>
                </th>
              )
            })}
          </tr>
        </thead>
        <tbody className={props.isLoading ? "opacity-25" : ""}>
          {/* <AnimatePresence> */}
          {props.data.map((node) => renderTreeNode(node))}
          {/* </AnimatePresence> */}
        </tbody>
      </table>
      {renderPagination()}
      {
        props.isLoading
        &&
        <div className="absolute inset-0 flex items-center justify-center bg-opacity-75 z-1">
          <span className="loading loading-spinner opacity-100"></span>
        </div>
      }
    </>
  );
};

// Example usage of TableTree component
// export const TreeTableApp = () => {
//   const sampleData: TreeNode[] = [
//     {
//       id: '1',
//       name: 'Root',
//       description: 'Root Node',
//       children: [
//         {
//           id: '2',
//           name: 'Child 1',
//           description: 'First Child',
//           children: [
//             {
//               id: '3',
//               name: 'Grandchild 1.1',
//               description: 'First Grandchild of Child 1',
//             },
//             {
//               id: '4',
//               name: 'Grandchild 1.2',
//               description: 'Second Grandchild of Child 1',
//             },
//           ],
//         },
//         {
//           id: '5',
//           name: 'Child 2',
//           description: 'Second Child',
//         },
//       ],
//     },
//   ];

//   const columns = [
//     {
//       key: 'name',
//       header: 'Name',
//       indentable: true,
//       sortable: true,
//     },
//     {
//       key: 'description',
//       header: 'Description',
//     },
//   ];

//   return (
//     <Table data={sampleData} columns={columns} />
//   );
// };

